﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.ItemCollectionElementViewExtensions
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using System;
using System.Collections.Generic;
using TaleWorlds.Core;
using TaleWorlds.DotNet;
using TaleWorlds.Engine;
using TaleWorlds.Library;

#nullable disable
namespace TaleWorlds.MountAndBlade.View
{
  public static class ItemCollectionElementViewExtensions
  {
    public static string GetMaterialCacheID(object o)
    {
      ItemRosterElement itemRosterElement = (ItemRosterElement) o;
      return !itemRosterElement.EquipmentElement.Item.IsCraftedWeapon ? "InventorySlot_" + itemRosterElement.EquipmentElement.Item.MultiMeshName : "";
    }

    public static MetaMesh GetMultiMesh(
      this ItemObject item,
      bool isFemale,
      bool hasGloves,
      bool needBatchedVersion)
    {
      MetaMesh multiMesh = (MetaMesh) null;
      if (item != null)
      {
        bool flag = false;
        if (item.HasArmorComponent)
          flag = item.ArmorComponent.MultiMeshHasGenderVariations;
        multiMesh = item.GetMultiMeshCopyWithGenderData(flag & isFemale, hasGloves, needBatchedVersion);
        if ((NativeObject) multiMesh == (NativeObject) null || multiMesh.MeshCount == 0)
          multiMesh = item.GetMultiMeshCopy();
      }
      return multiMesh;
    }

    public static MetaMesh GetMultiMesh(
      this EquipmentElement equipmentElement,
      bool isFemale,
      bool hasGloves,
      bool needBatchedVersion)
    {
      return equipmentElement.CosmeticItem == null ? equipmentElement.Item.GetMultiMesh(isFemale, hasGloves, needBatchedVersion) : equipmentElement.CosmeticItem.GetMultiMesh(isFemale, hasGloves, needBatchedVersion);
    }

    public static MetaMesh GetMultiMesh(
      this MissionWeapon weapon,
      bool isFemale,
      bool hasGloves,
      bool needBatchedVersion)
    {
      return weapon.Item.GetMultiMesh(isFemale, hasGloves, needBatchedVersion);
    }

    public static MetaMesh GetItemMeshForInventory(
      this ItemRosterElement rosterElement,
      bool isFemale = false)
    {
      return rosterElement.EquipmentElement.Item.ItemType != ItemObject.ItemTypeEnum.Arrows && rosterElement.EquipmentElement.Item.ItemType != ItemObject.ItemTypeEnum.Bolts ? rosterElement.EquipmentElement.GetMultiMesh(isFemale, false, false) : rosterElement.EquipmentElement.Item.GetHolsterMeshCopy();
    }

    public static MetaMesh GetHolsterMeshCopy(this ItemObject item)
    {
      if (item.WeaponDesign != (WeaponDesign) null)
      {
        MetaMesh holsterMesh = CraftedDataViewManager.GetCraftedDataView(item.WeaponDesign).HolsterMesh;
        return !((NativeObject) holsterMesh != (NativeObject) null) ? (MetaMesh) null : holsterMesh.CreateCopy();
      }
      return !string.IsNullOrEmpty(item.HolsterMeshName) ? MetaMesh.GetCopy(item.HolsterMeshName) : (MetaMesh) null;
    }

    public static MetaMesh GetHolsterMeshIfExists(this ItemObject item)
    {
      return !(item.WeaponDesign != (WeaponDesign) null) ? (MetaMesh) null : CraftedDataViewManager.GetCraftedDataView(item.WeaponDesign).HolsterMesh;
    }

    public static MetaMesh GetHolsterWithWeaponMeshCopy(
      this ItemObject item,
      bool needBatchedVersion)
    {
      if (item.WeaponDesign != (WeaponDesign) null)
      {
        CraftedDataView craftedDataView = CraftedDataViewManager.GetCraftedDataView(item.WeaponDesign);
        MetaMesh metaMesh = needBatchedVersion ? craftedDataView.HolsterMeshWithWeapon : craftedDataView.NonBatchedHolsterMeshWithWeapon;
        return !((NativeObject) metaMesh != (NativeObject) null) ? (MetaMesh) null : metaMesh.CreateCopy();
      }
      return !string.IsNullOrEmpty(item.HolsterWithWeaponMeshName) ? MetaMesh.GetCopy(item.HolsterWithWeaponMeshName) : (MetaMesh) null;
    }

    public static MetaMesh GetHolsterWithWeaponMeshIfExists(this ItemObject item)
    {
      return !(item.WeaponDesign != (WeaponDesign) null) ? (MetaMesh) null : CraftedDataViewManager.GetCraftedDataView(item.WeaponDesign).HolsterMeshWithWeapon;
    }

    public static MetaMesh GetFlyingMeshCopy(this ItemObject item, bool needBatchedVersion)
    {
      WeaponComponentData primaryWeapon = item.WeaponComponent?.PrimaryWeapon;
      if (item.WeaponDesign != (WeaponDesign) null && primaryWeapon != null)
      {
        if (!primaryWeapon.IsRangedWeapon || !primaryWeapon.IsConsumable)
          return (MetaMesh) null;
        CraftedDataView craftedDataView = CraftedDataViewManager.GetCraftedDataView(item.WeaponDesign);
        MetaMesh metaMesh = needBatchedVersion ? craftedDataView.WeaponMesh : craftedDataView.NonBatchedWeaponMesh;
        return !((NativeObject) metaMesh != (NativeObject) null) ? (MetaMesh) null : metaMesh.CreateCopy();
      }
      return !string.IsNullOrEmpty(item.FlyingMeshName) ? MetaMesh.GetCopy(item.FlyingMeshName) : (MetaMesh) null;
    }

    public static MetaMesh GetFlyingMeshIfExists(this ItemObject item)
    {
      if (item == null)
        return (MetaMesh) null;
      WeaponComponent weaponComponent = item.WeaponComponent;
      return weaponComponent == null ? (MetaMesh) null : weaponComponent.PrimaryWeapon.GetFlyingMeshIfExists(item);
    }

    internal static Material GetTableauMaterial(this ItemObject item, Banner banner)
    {
      Material tableauMaterial = (Material) null;
      if (item != null && item.IsUsingTableau)
      {
        Material material = (Material) null;
        MetaMesh multiMeshCopy1 = item.GetMultiMeshCopy();
        int meshCount = multiMeshCopy1.MeshCount;
        for (int meshIndex = 0; meshIndex < meshCount; ++meshIndex)
        {
          Mesh meshAtIndex = multiMeshCopy1.GetMeshAtIndex(meshIndex);
          if (!meshAtIndex.HasTag("dont_use_tableau"))
          {
            material = meshAtIndex.GetMaterial();
            meshAtIndex.ManualInvalidate();
            break;
          }
          meshAtIndex.ManualInvalidate();
        }
        multiMeshCopy1.ManualInvalidate();
        if (meshCount == 0 || (NativeObject) material == (NativeObject) null)
        {
          MetaMesh multiMeshCopy2 = item.GetMultiMeshCopy();
          Mesh meshAtIndex = multiMeshCopy2.GetMeshAtIndex(0);
          material = meshAtIndex.GetMaterial();
          meshAtIndex.ManualInvalidate();
          multiMeshCopy2.ManualInvalidate();
        }
        if (banner != null)
        {
          if ((NativeObject) material == (NativeObject) null)
            material = Material.GetDefaultTableauSampleMaterial(true);
          uint flagMask = (uint) material.GetShader().GetMaterialShaderFlagMask("use_tableau_blending");
          Dictionary<Tuple<Material, BannerCode>, Material> dictionary = (Dictionary<Tuple<Material, BannerCode>, Material>) null;
          if (ViewSubModule.BannerTexturedMaterialCache != null)
            dictionary = ViewSubModule.BannerTexturedMaterialCache;
          BannerCode from = BannerCode.CreateFrom(banner);
          if (dictionary != null)
          {
            if (dictionary.ContainsKey(new Tuple<Material, BannerCode>(material, from)))
            {
              tableauMaterial = dictionary[new Tuple<Material, BannerCode>(material, from)];
            }
            else
            {
              tableauMaterial = material.CreateCopy();
              Action<Texture> setAction = (Action<Texture>) (tex =>
              {
                tableauMaterial.SetShaderFlags(tableauMaterial.GetShaderFlags() | (ulong) flagMask);
                tableauMaterial.SetTexture(Material.MBTextureType.DiffuseMap2, tex);
              });
              banner.GetTableauTextureSmall(setAction);
              dictionary.Add(new Tuple<Material, BannerCode>(material, from), tableauMaterial);
            }
          }
          else
          {
            tableauMaterial = material.CreateCopy();
            Action<Texture> setAction = (Action<Texture>) (tex =>
            {
              tableauMaterial.SetShaderFlags(tableauMaterial.GetShaderFlags() | (ulong) flagMask);
              tableauMaterial.SetTexture(Material.MBTextureType.DiffuseMap2, tex);
            });
            banner.GetTableauTextureSmall(setAction);
          }
        }
      }
      return tableauMaterial;
    }

    public static MatrixFrame GetCameraFrameForInventory(this ItemRosterElement itemRosterElement)
    {
      return MatrixFrame.Identity;
    }

    public static MatrixFrame GetItemFrameForInventory(this ItemRosterElement itemRosterElement)
    {
      MatrixFrame frameForInventory = MatrixFrame.Identity;
      Mat3 identity = Mat3.Identity;
      float scaleFactor = 0.95f;
      Vec3 positionShift = new Vec3();
      MetaMesh meshForInventory = itemRosterElement.GetItemMeshForInventory();
      if ((NativeObject) meshForInventory != (NativeObject) null)
      {
        EquipmentElement equipmentElement = itemRosterElement.EquipmentElement;
        switch (equipmentElement.Item.ItemType)
        {
          case ItemObject.ItemTypeEnum.Horse:
          case ItemObject.ItemTypeEnum.Animal:
          case ItemObject.ItemTypeEnum.HorseHarness:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutUp(1.57079637f);
            break;
          case ItemObject.ItemTypeEnum.OneHandedWeapon:
          case ItemObject.ItemTypeEnum.TwoHandedWeapon:
          case ItemObject.ItemTypeEnum.Polearm:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutForward(-0.7853982f);
            break;
          case ItemObject.ItemTypeEnum.Arrows:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutForward(-0.7853982f);
            break;
          case ItemObject.ItemTypeEnum.Bolts:
          case ItemObject.ItemTypeEnum.Thrown:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutForward(-0.7853982f);
            break;
          case ItemObject.ItemTypeEnum.Shield:
            identity.RotateAboutUp(3.14159274f);
            break;
          case ItemObject.ItemTypeEnum.Bow:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutForward(-0.7853982f);
            break;
          case ItemObject.ItemTypeEnum.Crossbow:
            identity.RotateAboutForward(2.3561945f);
            identity.RotateAboutSide(-2.3561945f);
            identity.RotateAboutUp(-1.57079637f);
            break;
          case ItemObject.ItemTypeEnum.Goods:
            identity.RotateAboutSide(-1.0995574f);
            identity.RotateAboutUp(0.7853982f);
            break;
          case ItemObject.ItemTypeEnum.HeadArmor:
          case ItemObject.ItemTypeEnum.BodyArmor:
          case ItemObject.ItemTypeEnum.Cape:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutUp(3.14159274f);
            identity.RotateAboutSide(-3f * (float) Math.PI / 50f);
            break;
          case ItemObject.ItemTypeEnum.LegArmor:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutUp(3.14159274f);
            identity.RotateAboutSide(-0.314159274f);
            identity.RotateAboutUp(0.471238941f);
            break;
          case ItemObject.ItemTypeEnum.HandArmor:
            identity.RotateAboutSide(1.72787607f);
            scaleFactor = 2.1f;
            positionShift = new Vec3(y: -0.4f);
            break;
          case ItemObject.ItemTypeEnum.Book:
            identity.RotateAboutSide(-0.628318548f);
            identity.RotateAboutUp(-0.471238941f);
            break;
        }
        equipmentElement = itemRosterElement.EquipmentElement;
        if (equipmentElement.Item.IsCraftedWeapon)
          scaleFactor *= 0.55f;
        equipmentElement = itemRosterElement.EquipmentElement;
        frameForInventory = equipmentElement.Item.GetScaledFrame(identity, meshForInventory, scaleFactor, positionShift);
        equipmentElement = itemRosterElement.EquipmentElement;
        if (equipmentElement.Item.IsCraftedWeapon)
        {
          ref MatrixFrame local = ref frameForInventory;
          equipmentElement = itemRosterElement.EquipmentElement;
          double a = -0.0099999997764825821 * ((double) equipmentElement.Item.WeaponComponent.PrimaryWeapon.WeaponLength / 2.0);
          local.Elevate((float) a);
        }
      }
      return frameForInventory;
    }

    public static MatrixFrame GetItemFrameForItemTooltip(this ItemRosterElement itemRosterElement)
    {
      MatrixFrame frameForItemTooltip = MatrixFrame.Identity;
      Mat3 identity = Mat3.Identity;
      float scaleFactor = 0.85f;
      Vec3 positionShift = new Vec3();
      MetaMesh meshForInventory = itemRosterElement.GetItemMeshForInventory();
      EquipmentElement equipmentElement;
      if ((NativeObject) meshForInventory != (NativeObject) null)
      {
        equipmentElement = itemRosterElement.EquipmentElement;
        switch (equipmentElement.Item.ItemType)
        {
          case ItemObject.ItemTypeEnum.Horse:
          case ItemObject.ItemTypeEnum.Animal:
          case ItemObject.ItemTypeEnum.HorseHarness:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutUp(1.57079637f);
            scaleFactor = 0.65f;
            break;
          case ItemObject.ItemTypeEnum.OneHandedWeapon:
          case ItemObject.ItemTypeEnum.TwoHandedWeapon:
          case ItemObject.ItemTypeEnum.Polearm:
          case ItemObject.ItemTypeEnum.Bolts:
          case ItemObject.ItemTypeEnum.Bow:
          case ItemObject.ItemTypeEnum.Crossbow:
          case ItemObject.ItemTypeEnum.Thrown:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutForward(-0.7853982f);
            break;
          case ItemObject.ItemTypeEnum.Arrows:
            identity.RotateAboutSide(-1.57079637f);
            break;
          case ItemObject.ItemTypeEnum.Shield:
            identity.RotateAboutUp(2.261947f);
            break;
          case ItemObject.ItemTypeEnum.Goods:
            identity.RotateAboutSide(-1.0995574f);
            identity.RotateAboutUp(0.7853982f);
            break;
          case ItemObject.ItemTypeEnum.HeadArmor:
          case ItemObject.ItemTypeEnum.BodyArmor:
          case ItemObject.ItemTypeEnum.Cape:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutUp(3.14159274f);
            break;
          case ItemObject.ItemTypeEnum.LegArmor:
            identity.RotateAboutSide(-1.57079637f);
            identity.RotateAboutUp(3.14159274f);
            break;
          case ItemObject.ItemTypeEnum.HandArmor:
            identity.RotateAboutSide(1.57079637f);
            identity.RotateAboutSide(-0.251327425f);
            scaleFactor = 2.1f;
            positionShift = new Vec3(y: -0.4f);
            break;
          case ItemObject.ItemTypeEnum.Book:
            identity.RotateAboutSide(-0.628318548f);
            identity.RotateAboutUp(-0.471238941f);
            break;
        }
        equipmentElement = itemRosterElement.EquipmentElement;
        if (equipmentElement.Item.IsCraftedWeapon)
          scaleFactor *= 0.55f;
        equipmentElement = itemRosterElement.EquipmentElement;
        frameForItemTooltip = equipmentElement.Item.GetScaledFrame(identity, meshForInventory, scaleFactor, positionShift);
        frameForItemTooltip.origin.z -= 5f;
      }
      equipmentElement = itemRosterElement.EquipmentElement;
      if (equipmentElement.Item.IsCraftedWeapon)
      {
        ref MatrixFrame local = ref frameForItemTooltip;
        equipmentElement = itemRosterElement.EquipmentElement;
        double a = -0.0099999997764825821 * ((double) equipmentElement.Item.WeaponComponent.PrimaryWeapon.WeaponLength / 2.0);
        local.Elevate((float) a);
      }
      return frameForItemTooltip;
    }

    public static void OnGetWeaponData(
      ref WeaponData weaponData,
      MissionWeapon weapon,
      bool isFemale,
      Banner banner,
      bool needBatchedVersion)
    {
      MetaMesh multiMesh = weapon.GetMultiMesh(isFemale, false, needBatchedVersion);
      weaponData.WeaponMesh = multiMesh;
      MetaMesh holsterMeshCopy = weapon.Item.GetHolsterMeshCopy();
      weaponData.HolsterMesh = holsterMeshCopy;
      MetaMesh withWeaponMeshCopy = weapon.Item.GetHolsterWithWeaponMeshCopy(needBatchedVersion);
      weaponData.Prefab = weapon.Item.PrefabName;
      weaponData.HolsterMeshWithWeapon = withWeaponMeshCopy;
      MetaMesh flyingMeshCopy = weapon.Item.GetFlyingMeshCopy(needBatchedVersion);
      weaponData.FlyingMesh = flyingMeshCopy;
      Material tableauMaterial = weapon.Item.GetTableauMaterial(banner);
      weaponData.TableauMaterial = tableauMaterial;
    }
  }
}
